package com.denlaku.longan.core;

import com.denlaku.longan.Headers;
import com.denlaku.longan.vo.User;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Objects;
import java.util.Optional;

/**
 * 当前上下文辅助工具类
 *
 * @author tianx
 */
public class Current {
    /**
     * 获取当前上下文
     *
     * @return 当前上下文
     */
    public static RequestContext getCurrent() {
        return RequestContextManager.getCurrent();
    }

    /**
     * 获取当前用户信息
     *
     * @return 当前用户信息
     */
    public static User getUser() {
        RequestContext current = getCurrent();
        return Optional.ofNullable(current).map(RequestContext::getUser).orElse(null);
    }

    /**
     * 获取当前用户账号
     *
     * @return 当前用户账号
     */
    public static String getAccount() {
        RequestContext current = getCurrent();
        return Optional.ofNullable(current).map(RequestContext::getUser).map(User::getAccount).orElse(null);
    }

    /**
     * 获取当前用户ID
     *
     * @return 当前用户ID
     */
    public static Long getUserId() {
        RequestContext current = getCurrent();
        return Optional.ofNullable(current).map(RequestContext::getUser).map(User::getId).orElse(null);
    }

    /**
     * 获取租户ID
     *
     * @return 租户ID
     */
    public static Long getTenantId() {
        RequestContext current = getCurrent();
        return Optional.ofNullable(current).map(RequestContext::getHeaderMap).map(map -> map.get(Headers.X_TENANT_ID))
                .map(Current::parseLong).orElse(null);
    }

    private static Long parseLong(Object value) {
        if (value instanceof Long) {
            return (Long) value;
        }
        return null;
    }

    /**
     * 获取当前用户时区ID
     *
     * @return 当前用户时区ID
     */
    public static String getZoneId() {
        RequestContext current = getCurrent();
        return Optional.ofNullable(current).map(RequestContext::getHeaderMap).map(map -> map.get(Headers.X_ZONE_ID))
                .map(value -> Objects.toString(value, null)).orElse(null);
    }

    /**
     * 获取当前用户时区偏移ID
     *
     * @return 当前用户时区偏移ID
     */
    public static String getZoneOffsetId() {
        RequestContext current = getCurrent();
        return Optional.ofNullable(current).map(RequestContext::getHeaderMap)
                .map(map -> map.get(Headers.X_ZONE_OFFSET_ID)).map(value -> Objects.toString(value, null))
                .orElse(null);
    }

    /**
     * 获取当前用户时区偏移
     *
     * @return 当前用户时区偏移
     */
    public static ZoneOffset getZoneOffset() {
        String zoneId = getZoneId();
        if (zoneId != null) {
            OffsetDateTime.now(ZoneId.of(zoneId));
        }
        return Optional.ofNullable(getZoneOffsetId()).map(ZoneOffset::of).orElse(null);
    }

    /**
     * 获取当前请求对象
     *
     * @return 当前请求对象
     */
    public HttpServletRequest getRequest() {
        if (RequestContextHolder.getRequestAttributes() instanceof ServletRequestAttributes requestAttributes) {
            return requestAttributes.getRequest();
        }
        return null;
    }

}
